package org.datamining.gui.windows;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileNameExtensionFilter;

import net.java.dev.designgridlayout.DesignGridLayout;

import org.apache.commons.io.FilenameUtils;
import org.datamining.apriori.custom.AprioriManager;
import org.datamining.apriori.custom.AttributeSelectionPanel;
import org.datamining.apriori.custom.ItemSet;
import org.datamining.utilities.PropertyFileLoader;
import org.datamining.utilities.PropertyProvider;

import weka.filters.unsupervised.attribute.Remove;


/**
 * @author Betul Coskuner coskunerbetul@gmail.com
 * @since 18th May 2014
 *
 *	Bu sinif AprioriSwingApplication uygulamasinin ana penceresidir
 *	Form elemanlari ve elemanlara bagli olaylar yer alir
 *
 */
public class MainWindow extends AbstractWindow {

	//Form Elemanlari
	private JLabel lblSelectFile;
	private JLabel lblResults;
	private JComboBox<Integer> cmbNumberOfRules;
	private JComboBox<Double> cmbDeltaValue;
	private JComboBox<Double> cmbMinConfidence;
	private JComboBox<Double> cmbMinSupport;
	private JButton btnBrowse;
	private JButton btnRunApriori;
	private File fileSelectedARFF;
	private JTextArea rtAprioriResult;
	private JScrollPane rtScrollPane;
	private AttributeSelectionPanel pnlAttributeSelection;
	private JButton btnRemove;
	private JButton btnClearFilter;
	private JPanel pnlResults;
	
	
	private PropertyFileLoader arayuzSozlugu = PropertyProvider.getGuiLanguageData();
	private PropertyFileLoader kelimeDegistirici = PropertyProvider.getDatasetWordSubstitutions();

	// Formu olusturan kisim burasidir. Uygulama calistirildiginde AbstractWindow tarafindan otomatik cagrilir
	@Override
	protected JPanel build(DesignGridLayout layout) {

		//Kural Sayisi
		Integer[] listInteger = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20 };
		cmbNumberOfRules = new JComboBox<Integer>(listInteger);

		//Delta Degeri
		Double[] listDouble = { 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20 };
		cmbDeltaValue = new JComboBox<Double>(listDouble);

		//Minimum Guven
		Double[] listMinMetric = { 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95 };
		cmbMinConfidence = new JComboBox<Double>(listMinMetric);
		cmbMinConfidence.setSelectedIndex(11);

		//Minimum Destek
		Double[] listMinSupport = { 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20 };
		cmbMinSupport = new JComboBox<Double>(listMinSupport);
		cmbMinSupport.setSelectedIndex(4);

		//Dosya Sec butonu
		btnBrowse = new JButton(arayuzSozlugu.getLanguageDataValue("button.browse"));
		btnBrowse.addActionListener(btnBrowseClickListener);
		
		//Dosya Yolu: .... label'i
		lblSelectFile = new JLabel(arayuzSozlugu.getLanguageDataValue("label.selectfile"));
		
		
		// Simdi Calistir butonu
		btnRunApriori = new JButton(arayuzSozlugu.getLanguageDataValue("button.runapriori"));
		btnRunApriori.addActionListener(btnRunAprioriClickListener);
		btnRunApriori.setEnabled(false);
		
		// Sonuc listesi surukleme cubugu icerisine gomulur ve forma surukleme cubugu eklenir
		rtAprioriResult = new JTextArea(arayuzSozlugu.getLanguageDataValue("richtext.apriori"));
		rtAprioriResult.setFont(new Font("Comic Sans MS", Font.PLAIN, 13));
		rtAprioriResult.setEditable(false);
		rtScrollPane = new JScrollPane(rtAprioriResult);
		rtScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		rtScrollPane.setPreferredSize(new Dimension(400, 250));
		
		// Ozellik secim paneli
		pnlAttributeSelection = new AttributeSelectionPanel();
		pnlAttributeSelection.getSelectionModel().addListSelectionListener(pnlAttributeSelection_SelectionListener);

		//Secili ozellikleri Sil butonu
		btnRemove = new JButton(arayuzSozlugu.getLanguageDataValue("button.remove"));
		btnRemove.setEnabled(false);
		btnRemove.addActionListener(btnRemoveClickListener);

		//Filtre kaldir butonu
		btnClearFilter = new JButton(arayuzSozlugu.getLanguageDataValue("button.clearfilter"));
		btnClearFilter.setEnabled(false);
		btnClearFilter.addActionListener(btnClearFilterClickListener);
		
		//Sonuc label'i filtre hakkinda bilgi vermesi gerektigi icin degiskende tutuluyor
		lblResults = new JLabel(arayuzSozlugu.getLanguageDataValue("label.results"));
		
		//Sonuc paneli label ve surukleme cubugunu icerir
		pnlResults = new JPanel(new BorderLayout());
		pnlResults.add(lblResults, BorderLayout.NORTH);
		pnlResults.add(rtScrollPane, BorderLayout.CENTER);
		pnlResults.setPreferredSize(new Dimension(500, 1));

		//ANA FORM TASARIMI
		// DesignGridLayout'a eleman ekleme
		layout.row().grid().add(newLabel(arayuzSozlugu.getLanguageDataValue("label.selectarff"))).add(btnBrowse);
		layout.emptyRow();
		layout.row().grid().add(lblSelectFile);
		layout.emptyRow();
		layout.row().grid().add(newLabel(arayuzSozlugu.getLanguageDataValue("label.numofrules"))).add(cmbNumberOfRules);
		layout.row().grid().add(newLabel(arayuzSozlugu.getLanguageDataValue("label.delta"))).add(cmbDeltaValue);
		layout.row().grid().add(newLabel(arayuzSozlugu.getLanguageDataValue("label.minconf"))).add(cmbMinConfidence);
		layout.row().grid().add(newLabel(arayuzSozlugu.getLanguageDataValue("label.minsup"))).add(cmbMinSupport);
		layout.emptyRow();
		layout.row().grid().add(newLabel(arayuzSozlugu.getLanguageDataValue("label.attrlist")));
		layout.row().grid().add(pnlAttributeSelection);
		layout.row().grid().add(btnClearFilter).add(btnRemove).add(btnRunApriori);
		
		return this.pnlResults;
	}

	// btnBrowse (Dosya Sec) butonu icin Click olayi
	ActionListener btnBrowseClickListener = new ActionListener() {
		@Override
		public void actionPerformed(ActionEvent e) {

			//Open File Dialog benzeri bir form elemanidir
			JFileChooser fc = new JFileChooser();
			FileNameExtensionFilter filter = new FileNameExtensionFilter("Attribute-Relation File Format (ARFF)", "arff");
			fc.setFileFilter(filter);
			fc.setApproveButtonText(arayuzSozlugu.getLanguageDataValue("filechooser.approvebutton.text"));
			fc.setApproveButtonToolTipText(arayuzSozlugu.getLanguageDataValue("filechooser.approvebutton.tooltip"));

			int dialogResult = fc.showOpenDialog(_frame);
			
			if (dialogResult == JFileChooser.APPROVE_OPTION) {
				fileSelectedARFF = fc.getSelectedFile();
				// Dosya yolunu fileSelectedARFF.getAbsolutePath() ile elde edebiliriz
				lblSelectFile.setText(arayuzSozlugu.getLanguageDataValue("label.selectfile") + fileSelectedARFF.getAbsolutePath());

				String dosyauzantisi = FilenameUtils.getExtension(fileSelectedARFF.getAbsolutePath());

				if (dosyauzantisi.equals("arff")) {
					btnRunApriori.setEnabled(true);

					AprioriManager.ElemanlariBagla(pnlAttributeSelection, btnRemove);
					AprioriManager.veriSetiHazirla(fileSelectedARFF.getAbsolutePath());
					refreshWindow();
				} else {
					btnRunApriori.setEnabled(false);
					JOptionPane.showMessageDialog(_frame, arayuzSozlugu.getLanguageDataValue("message.1.text"),
							arayuzSozlugu.getLanguageDataValue("message.1.title"), JOptionPane.ERROR_MESSAGE);
				}
			}
		}
	};

	// btnRunApriori 'Simdi Calistir' butonu icin click olayi
	ActionListener btnRunAprioriClickListener = new ActionListener() {
		@Override
		public void actionPerformed(ActionEvent ae) {
			 
			//Filtre degerleri set edilir
			//System.out.println("Last Selected Item: " + lastSelectedComboBoxItem);
			ItemSet.AprioriFilterArgs.attrValue = kelimeDegistirici.getReverseSubstitution(lastSelectedComboBoxItem);
			
			//AprioriArgs degiskeni Apriori'nin calismasi icin gerekli bilgilerin toplandigi 
			//Parametre aktarim amacli bir siniftir.
			AprioriManager.AprioriArgs a = new AprioriManager.AprioriArgs();
			a.filePath = fileSelectedARFF.getAbsolutePath();
			a.deltaValue = (double) cmbDeltaValue.getSelectedItem();
			a.numberOfRules = (int) cmbNumberOfRules.getSelectedItem();
			a.output = rtAprioriResult;
			a.minConfidence = (double) cmbMinConfidence.getSelectedItem();
			a.minSupport = (double) cmbMinSupport.getSelectedItem();
			AprioriManager.simdiCalistir(a);
		}
	};

	//Secili Ozellikleri Sil Butonu icin olay
	ActionListener btnRemoveClickListener = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			
			try {
				Remove r = new Remove();
				int[] selected = pnlAttributeSelection.getSelectedAttributes();
				if (selected.length == 0) {
					return;
				}
				if (selected.length == AprioriManager.getInstances().numAttributes()) {
					// Hata mesaji gosterilir
					JOptionPane.showMessageDialog(_frame, arayuzSozlugu.getLanguageDataValue("message.2.text"),
							arayuzSozlugu.getLanguageDataValue("message.2.title"), JOptionPane.ERROR_MESSAGE);
					return;
				}
				r.setAttributeIndicesArray(selected);
				AprioriManager.applyFilter(r);
				btnRemove.setEnabled(false);
			} catch (Exception ex) {
				JOptionPane.showMessageDialog(_frame, arayuzSozlugu.getLanguageDataValue("message.3.text") + ex.getMessage(),
						arayuzSozlugu.getLanguageDataValue("message.3.title"), JOptionPane.ERROR_MESSAGE);
			}
		}
	};

	//Son secilen comboBox metnini icinde tutan degisken. Yalnizca burada elde edip
	//Bu metni baska yerlerde kullanabildigimiz icin boyle bir seye gerek duyduk
	private String lastSelectedComboBoxItem;
	
	// Listeden ozellik secildiginde olanlar
	//FIXME: Secilen satirdan baskasi secildiginde tetikleniyor. Icindeki combobox'larin degeri degistiginde
	// Bunu arka planda yapsa da gorsele tasiyamiyor
	ListSelectionListener pnlAttributeSelection_SelectionListener = new ListSelectionListener() {
		public void valueChanged(ListSelectionEvent e) {
			if (!e.getValueIsAdjusting()) {
				ListSelectionModel lm = (ListSelectionModel) e.getSource();
				for (int i = e.getFirstIndex(); i <= e.getLastIndex(); i++) {
					if (lm.isSelectedIndex(i)) {
						
						if(pnlAttributeSelection.getSelectedAttributeCount() > 0)
							btnRemove.setEnabled(true);
						else
							btnRemove.setEnabled(false);
						
						btnClearFilter.setEnabled(true);
						
						//filtrelenecek kriter ismini ayarla
						//Panelde hangi satirdakiyse ona gore set eder
						ItemSet.AprioriFilterArgs.attrName = AprioriManager.getInstances().attribute(i).name();
						lastSelectedComboBoxItem = (String)pnlAttributeSelection.getSelectedComboBoxObject(i);
						//System.out.println("Last Selected Item: " + lastSelectedComboBoxItem);
						
						//Sonuc label'inin metnini ayarla
						lblResults.setText(arayuzSozlugu.getLanguageDataValue("label.results.filtered")
								+ kelimeDegistirici.getSubstitution(AprioriManager.getInstances().attribute(i).name())
								+ "="
								+ kelimeDegistirici.getSubstitution(lastSelectedComboBoxItem)
								+ ")" );
						
						refreshWindow();
						break;
					}
				}
			}
		}
	};
	
	//Filtre secimini temizler
		ActionListener btnClearFilterClickListener = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				lblResults.setText(arayuzSozlugu.getLanguageDataValue("label.results"));
				ItemSet.AprioriFilterArgs.attrName = "";
				ItemSet.AprioriFilterArgs.attrValue = "";
				btnClearFilter.setEnabled(false);
				refreshWindow();
			}
		};
	
}
